package com.quikin.persistence.stdjpa.controller;

import java.util.Collection;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.quikin.persistence.stdjpa.util.PersistenceConfigure;
import com.von.platform.impl.openjpa.std.EntityManagerContanier;
import com.von.platform.orm.TransactionErrCode;
import com.von.platform.orm.TransactionException;

abstract public class AbstractController<T, PK> {

    public T find(PK key) {
        EntityManager em = getEntityManager();
        return em.find(getEntityClass(), key);
    }
    
    abstract protected Class<T> getEntityClass();
    
    protected EntityManager getEntityManager() {
        EntityManager em = EntityManagerContanier.getInstance().getCurrentEntityManager(PersistenceConfigure.getInstance().getCurrentPUName());
        if (em == null) {
            throw new TransactionException(TransactionErrCode.TRANSACTION_NOT_BEGAN);
        }
        return em;
    }
    
    @SuppressWarnings("unchecked")
    public Collection<T> find(String queryName, Map<String,Object> params, Class<T> clz) {
        EntityManager em = getEntityManager();
        Query query = em.createNamedQuery(queryName, clz);
        for (String str : params.keySet()) {
            query.setParameter(str, params.get(str));
        }
        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public Collection<T> find(String queryName, Map<String,Object> params) {
        EntityManager em = getEntityManager();
        Query query = em.createNamedQuery(queryName);
        for (String str : params.keySet()) {
            query.setParameter(str, params.get(str));
        }
        return query.getResultList();
    }
    
    @SuppressWarnings("unchecked")
    public Collection<T> findBySQL(String queryName, Map<String,Object> params, Class<T> clz) {
        EntityManager em = getEntityManager();
        Query query = em.createQuery(queryName, clz);
        for (String str : params.keySet()) {
            query.setParameter(str, params.get(str));
        }
        return query.getResultList();
    }
    
    @SuppressWarnings("unchecked")
    public Collection<T> findBySQL(String queryName, Map<String,Object> params) {
        EntityManager em = getEntityManager();
        Query query = em.createQuery(queryName);
        for (String str : params.keySet()) {
            query.setParameter(str, params.get(str));
        }
        return query.getResultList();
    }
    
    public void update(T value) {
        EntityManager em = getEntityManager();
        em.merge(value);
    }
}
